package icu.sunway.gushenBlogBackEnd.Service.Implement;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import icu.sunway.gushenBlogBackEnd.Entity.Data.ArticleDO;
import icu.sunway.gushenBlogBackEnd.Entity.Data.UserDO;
import icu.sunway.gushenBlogBackEnd.Entity.View.Article.ArticlePostVO;
import icu.sunway.gushenBlogBackEnd.Entity.View.Article.ArticleUpdateVO;
import icu.sunway.gushenBlogBackEnd.Entity.View.ResultVO;
import icu.sunway.gushenBlogBackEnd.Mapper.ArticleMapper;
import icu.sunway.gushenBlogBackEnd.Message.ArticleMessage;
import icu.sunway.gushenBlogBackEnd.Service.ArticleService;
import icu.sunway.gushenBlogBackEnd.utils.DateUtils;
import icu.sunway.gushenBlogBackEnd.utils.JwtUtil;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, ArticleDO> implements ArticleService {

    final UserServiceImpl userServiceImpl;

    ArticleServiceImpl(UserServiceImpl userServiceImpl) {
        this.userServiceImpl = userServiceImpl;
    }

    @Override
    public ResultVO<List<ArticleDO>> getArticleList() {
        QueryWrapper<ArticleDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("publish_time");
        return new ResultVO<>(200, ArticleMessage.get_success, list(queryWrapper));
    }

    @Override
    public ResultVO<List<ArticleDO>> getArticleListByPage(int curPage, int pageSize) {
        Page<ArticleDO> page = new Page<>(curPage, pageSize);
        QueryWrapper<ArticleDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("publish_time");
        IPage<ArticleDO> articleDOIPage = page(page, queryWrapper);
        List<ArticleDO> articleDOList = articleDOIPage.getRecords();
        return new ResultVO<>(200, ArticleMessage.get_success, articleDOList);
    }

    @Override
    public ResultVO<Long> getArticleCount() {
        long count = count(null);
        return new ResultVO<>(200, ArticleMessage.get_count_success, count);
    }

    @Override
    public ResultVO<ArticleDO> getArticleById(String id) {
        ArticleDO articleDO = getById(id);
        if (articleDO == null) {
            return new ResultVO<>(400, ArticleMessage.article_not_exist, null);
        }
        return new ResultVO<>(200, ArticleMessage.article_get_success, articleDO);
    }

    @Override
    public ResultVO<Boolean> addArticle(ArticlePostVO articlePostVO, String token) {
        try {
            UserDO userDO = userServiceImpl.getUserById(JwtUtil.parseTokenAsId(token));
            save(new ArticleDO(
                    null,
                    articlePostVO.getTitle(),
                    articlePostVO.getContent(),
                    userDO.getId(),
                    userDO.getNickname(),
                    DateUtils.getCurDateString(),
                    articlePostVO.getIntroduction()
            ));
        } catch (Exception e) {
            return new ResultVO<>(400, ArticleMessage.add_article_fail, false);
        }
        return new ResultVO<>(200, ArticleMessage.add_article_success, true);
    }

    @Override
    public ResultVO<Boolean> updateArticle(ArticleUpdateVO articleUpdateVO) {
        try {
            UpdateWrapper<ArticleDO> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("id", articleUpdateVO.getId());
            updateWrapper.set("title", articleUpdateVO.getTitle());
            updateWrapper.set("content", articleUpdateVO.getContent());
            updateWrapper.set("introduction", articleUpdateVO.getIntroduction());
            update(updateWrapper);
        } catch (Exception e) {
            return new ResultVO<>(400, ArticleMessage.article_update_fail, false);
        }
        return new ResultVO<>(200, ArticleMessage.article_update_success, true);
    }

    @Override
    public ResultVO<Boolean> deleteArticle(String id) {
        try {
            removeById(id);
        } catch (Exception e) {
            return new ResultVO<>(400, ArticleMessage.article_delete_fail, false);
        }
        return new ResultVO<>(200, ArticleMessage.article_delete_success, true);
    }
}
